/**
 * 请求模块
 */

import axios from 'axios'
import store from '@/store'
import router from '@/router/'
import JSONBig from 'json-bigint'
import { Toast } from 'vant'

// JSONBig.parse()
// JSONBig.stringify()
const refreshTokenReq = axios.create({
  baseURL: 'http://api-toutiao-web.itheima.net'
})

const request = axios.create({
  // 接口的基准路径
  baseURL: 'http://api-toutiao-web.itheima.net',

  // 自定义后端返回的原始数据
  transformResponse: [
    function(data) {
      // axios 默认会在内部这样来处理后端返回的数据
      try {
        return JSONBig.parse(data)
      } catch (error) {
        return data
      }
    }
  ]
})

// 请求拦截器
// Add a request interceptor
request.interceptors.request.use(
  function(config) {
    // 请求发起经过这里
    // config：本次请求的请求配置对象
    const { user } = store.state
    if (user && user.token) {
      config.headers.Authorization = `Bearer ${user.token}`
    }

    // 请注意：这里务必要返回 cofig 配置对象，否则请求停在这里出不去了
    return config
  },
  function(error) {
    // 如果请求出错了，(还没有发出去)
    return Promise.reject(error)
  }
)

// 响应拦截器
// Add a response interceptor
request.interceptors.response.use(
  response => {
    // Any status code that lie within the range of 2xx cause this function to trigger
    // Do something with response data
    return response
  },
  async error => {
    // Any status codes that falls outside the range of 2xx cause this function to trigger
    // Do something with response error
    const status = error.response.status

    if (status === 400) {
      // 客户端请求数据错误
      Toast.fail('客户端请求参数异常')
    } else if (status === 401) {
      // token 无效
      // 如果没有 user 或者 user.token，直接去登陆
      const { user } = store.state

      if (!user || !user.token) {
        return redirectLogin()
      }
      // 使用 refresh_token ,则请求获取新的tokens
      try {
        const { data } = await refreshTokenReq({
          method: 'PUT',
          url: '/app/v1_0/authorizations',
          headers: {
            Authorization: `Bearer ${user.refresh_token}`
          }
        })

        // 拿到新的 token 之后把他更新到容器中文
        user.token = data.data.token
        store.commit('setUser', user)
        // 那失败的请求重新发出去
        return request(error.config)
      } catch (error) {
        // 刷新 token 都失败了，直接跳转登录页
        redirectLogin()
      }
    } else if (status === 403) {
      // 没有权限操作
      Toast.fail('没有权限操作')
    } else if (status >= 500) {
      // 服务端异常
      Toast.fail('服务端异常，请稍后重试')
    }

    // 抛出异常
    return Promise.reject(error)
  }
)

function redirectLogin() {
  router.replace({
    name: 'login',
    // 传递查询参数
    query: {
      redirect: router.currentRoute.fullPath
    }
  })
}

export default request
